#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/poll.h>
 
#define MAXLNE  4096
#define POLL_SIZE	1024


int main(int argc, char*argv[]){
    int listenfd, connfd, n;
    struct sockaddr_in servaddr;
    char buff[MAXLNE];
 
    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
        return 0;
    }
 
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(9999);
 
    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
        return 0;
    }
 
    if (listen(listenfd, 10) == -1) {
        printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);
        return 0;
    }    

//主逻辑
    struct pollfd fds[POLL_SIZE] = {0};
    fds[0].fd = listenfd;
    fds[0].events = POLLIN;
    
    int max_fd = listenfd;

    int i = 0;
    for (i = 1;i < POLL_SIZE;i ++) {
        fds[i].fd = -1;
    }
    
    while (1) {  
        int nready = poll(fds, max_fd + 1, -1);
    
        if (fds[0].revents & POLLIN) {
            struct sockaddr_in client;
            socklen_t len = sizeof(client);
            if ((connfd = accept(listenfd, (struct sockaddr *)&client, &len)) == -1) {
                printf("accept socket error: %s(errno: %d)\n", strerror(errno), errno);
                return 0;
            }
    
            printf("accept \n");
            fds[connfd].fd = connfd;
            fds[connfd].events = POLLIN;
    
            if (connfd > max_fd) max_fd = connfd;
    
            if (--nready == 0) continue;
        }
    
        //int i = 0;
        for (i = listenfd + 1; i <= max_fd; i++)  {
            if (fds[i].revents & POLLIN) {     
                n = recv(i, buff, MAXLNE, 0);
                if (n > 0) {
                    buff[n] = '\0';
                    printf("recv msg from client: %s\n", buff);
                    send(i, buff, n, 0);
                } else if (n == 0) { //
                    printf("client disconect!\n");
                    fds[i].fd = -1;    
                    close(i);                    
                }
                if (--nready == 0) break;
            }
        }    
    }
    close(listenfd);
    return 0;
}
